package edu.scsu.csci.core;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

import edu.scsu.csci.util.ReflectionUtil;



/**
 * An adapter for the {@link java.lang.reflect.Field}.
 * 
 * @author Maqbool Khan
 * @since jdk 1.5
 * @see
 * @viz.diagram DOField.tpx
 */
public class DOField {
	
	/**
	 * the domain object.
	 */
	private Object domainObject;
	
	/**
	 * the domain object's field.
	 */
	private Field field;
	
	/**
	 * the type of the field.
	 */
	private Class<?> type;
	
	/**
	 * @param field
	 * @param value
	 */
	public DOField(Field field, Object domainObject){
		this.field = field;
		this.domainObject = domainObject;
		this.type = field.getType();
	}
	
	/**
	 * Returns the field's name
	 * 
	 * @return the name
	 */
	public String getName() {
		return this.field.getName();
	}

	@Override
	public String toString() {
		return "[Field: " + getName() + "]";
	}
	
	/**
	 * Returns the field's type.
	 * 
	 * @return
	 */
	public Class<?> getType(){
		return this.type;
	}
	
	/**
	 * Returns true if the field contains annotations.
	 * 
	 * @param <T>
	 * @param type
	 * @return
	 */
	public <T extends Annotation> boolean isAnnotationPresent(Class<T> type) {
		return this.field.isAnnotationPresent(type);
	}
	
	/**
	 * Returns the annotation defined for <code>field</code> with <code>annotationClass</code> as the class.
	 * 
	 * @param <T>
	 * @param annotationClass
	 * @return
	 */
	public <T extends Annotation> Annotation getAnnotation(Class<T> annotationClass)	{
		return this.field.getAnnotation(annotationClass);
	}
	
	/**
	 * Sets the field value to <code>value</code>
	 * 
	 * @param value
	 */
	public void set(Object value){
		this.field.setAccessible(true);
		ReflectionUtil.setField(this.domainObject, this.field, value);
	}
}
